using System;
using System.Text;

/****************************************************
// 功能：将c# 的byte[] 转换成 Netty 的 ByteBuf
// 2种计算机语言，本质上协议都是通用的，只是传输的数据格式必须双方协商好
// | Talk To [ 聊来改善地区金融服务环境，助力企业发展 ]
// | Copyright (c) 2021-2025 聊来 All rights reserved.
// | Licensed ( <a href="http://www.apache.org/licenses/LICENSE-2.0">聊来</a> )
// | @Author: 贯彻己道的云 <18970881148@qq.com>
// | DateTime: 2025/2/11 14:34:18
*****************************************************/

public class ByteBuf
{
    private byte[] data;
    private int readerIndex;
    private int writerIndex;
    private int markReader;
    private int markWriter;

    /// <summary>
    /// 初始化
    /// </summary>
    /// <param name="capacity"></param>
    public ByteBuf(int capacity)
    {
        this.data = new byte[capacity];
        readerIndex = 0;
        writerIndex = 0;
        markReader = 0;
        markWriter = 0;
    }

    public ByteBuf(byte[] content)
    {
        this.data = content;
        readerIndex = 0;
        writerIndex = content.Length;
        markReader = 0;
        markWriter = 0;
    }

    private ByteBuf()
    {
    }

    /// <summary>
    /// 容量
    /// </summary>
    /// <returns></returns>
    public int Capacity()
    {
        return data.Length;
    }

    /// <summary>
    /// 扩容
    /// </summary>
    /// <param name="nc"></param>
    /// <returns></returns>
    public ByteBuf Capacity(int nc)
    {
        if (nc > data.Length)
        {
            byte[] old = data;
            data = new byte[nc];
            Array.Copy(old, data, old.Length);
        }

        return this;
    }

    /// <summary>
    /// 清除掉所有标记
    /// </summary>
    /// <returns></returns>
    public ByteBuf Clear()
    {
        readerIndex = 0;
        writerIndex = 0;
        markReader = 0;
        markWriter = 0;
        return this;
    }

    /// <summary>
    /// 拷贝
    /// </summary>
    /// <returns></returns>
    public ByteBuf Copy()
    {
        ByteBuf item = new ByteBuf(data.Length);
        Array.Copy(this.data, item.data, data.Length);
        item.readerIndex = readerIndex;
        item.writerIndex = writerIndex;
        item.markReader = markReader;
        item.markWriter = markWriter;
        return item;
    }

    /// <summary>
    /// 浅拷贝
    /// </summary>
    /// <returns></returns>
    public ByteBuf Duplicate()
    {
        ByteBuf item = new ByteBuf();
        item.readerIndex = readerIndex;
        item.writerIndex = writerIndex;
        item.markReader = markReader;
        item.markWriter = markWriter;
        item.data = data;
        return item;
    }

    /**
		 * 获取一个字节
		 **/
    public byte GetByte(int index)
    {
        if (index < data.Length)
        {
            return data[index];
        }

        return (byte)0;
    }

    /// <summary>
    /// 读取四字节整形
    /// </summary>
    /// <param name="index"></param>
    /// <returns></returns>
    public int GetInt(int index)
    {
        if (index + 3 < data.Length)
        {
            int ret = ((int)data[index]) << 24;
            ret |= ((int)data[index + 1]) << 16;
            ret |= ((int)data[index + 2]) << 8;
            ret |= ((int)data[index + 3]);
            return ret;
        }

        return 0;
    }

    /// <summary>
    /// 小头的读取
    /// </summary>
    /// <param name="index"></param>
    /// <returns></returns>
    public int GetIntLE(int index)
    {
        if (index + 3 < data.Length)
        {
            int ret = ((int)data[index]);
            ret |= ((int)data[index + 1]) << 8;
            ret |= ((int)data[index + 2]) << 16;
            ret |= ((int)data[index + 3]) << 24;
            return ret;
        }

        return 0;
    }

    /**
		 * 读取两字节整形
		 **/
    public short GetShort(int index)
    {
        if (index + 1 < data.Length)
        {
            short r1 = (short)(data[index] << 8);
            short r2 = (short)(data[index + 1]);
            short ret = (short)(r1 | r2);
            return ret;
        }

        return 0;
    }

    /// <summary>
    /// 读取两字节整形
    /// </summary>
    /// <param name="index"></param>
    /// <returns></returns>
    public short GetShortLE(int index)
    {
        if (index + 1 < data.Length)
        {
            short r1 = (short)(data[index]);
            short r2 = (short)(data[index + 1] << 8);
            short ret = (short)(r1 | r2);
            return ret;
        }

        return 0;
    }

    /**
		 * 标记读
		 **/
    public ByteBuf MarkReaderIndex()
    {
        markReader = readerIndex;
        return this;
    }

    /**
		 * 标记写
		 **/
    public ByteBuf MarkWriterIndex()
    {
        markWriter = writerIndex;
        return this;
    }

    /**
		 * 可写长度
		 **/
    public int MaxWritableBytes()
    {
        return data.Length - writerIndex;
    }

    /**
		 * 读取一个字节
		 **/
    public byte ReadByte()
    {
        if (readerIndex < writerIndex)
        {
            byte ret = data[readerIndex++];
            return ret;
        }

        return (byte)0;
    }

    /**
		 * 读取四字节整形
		 **/
    public int ReadInt()
    {
        if (readerIndex + 3 < writerIndex)
        {
            int ret = (int)(((data[readerIndex++]) << 24) & 0xff000000);
            ret |= (((data[readerIndex++]) << 16) & 0x00ff0000);
            ret |= (((data[readerIndex++]) << 8) & 0x0000ff00);
            ret |= (((data[readerIndex++])) & 0x000000ff);
            return ret;
        }

        return 0;
    }

    /// <summary>
    /// 小头读取
    /// </summary>
    /// <returns></returns>
    public int ReadIntLE()
    {
        if (readerIndex + 3 < writerIndex)
        {
            int ret = (((data[readerIndex++])) & 0x000000ff);
            ret |= (((data[readerIndex++]) << 8) & 0x0000ff00);
            ret |= (((data[readerIndex++]) << 16) & 0x00ff0000);
            ret |= (int)(((data[readerIndex++]) << 24) & 0xff000000);
            return ret;
        }

        return 0;
    }

    /// <summary>
    /// 读取两个字节的整形
    /// </summary>
    /// <returns></returns>
    public short ReadShort()
    {
        if (readerIndex + 1 < writerIndex)
        {
            int h = data[readerIndex++];
            int l = data[readerIndex++] & 0x000000ff;
            int len = ((h << 8) & 0x0000ff00) | (l);
            return (short)len;
        }

        return 0;
    }

    /// <summary>
    /// 小头读取
    /// </summary>
    /// <returns></returns>
    public short ReadShortLE()
    {
        if (readerIndex + 1 < writerIndex)
        {
            int l = data[readerIndex++];
            int h = data[readerIndex++] & 0x000000ff;
            int len = ((h << 8) & 0x0000ff00) | (l);
            return (short)len;
        }

        return 0;
    }

    /// <summary>
    /// 可读字节数
    /// </summary>
    /// <returns></returns>
    public int ReadableBytes()
    {
        return writerIndex - readerIndex;
    }

    /**
		 * 读指针
		 **/
    public int ReaderIndex()
    {
        return readerIndex;
    }

    /**
		 * 移动读指针
		 **/
    public ByteBuf ReaderIndex(int readerIndex)
    {
        if (readerIndex <= writerIndex)
        {
            this.readerIndex = readerIndex;
        }

        return this;
    }

    /**
		 * 重置读指针
		 **/
    public ByteBuf ResetReaderIndex()
    {
        if (markReader <= writerIndex)
        {
            this.readerIndex = markReader;
        }

        return this;
    }

    /**
		 * 重置写指针
		 **/
    public ByteBuf ResetWriterIndex()
    {
        if (markWriter >= readerIndex)
        {
            writerIndex = markWriter;
        }

        return this;
    }

    /**
		 * 设置字节
		 **/
    public ByteBuf SetByte(int index, byte value)
    {
        if (index < data.Length)
        {
            data[index] = value;
        }

        return this;
    }


    /**
		 * 设置字节
		 **/
    public ByteBuf SetBytes(int index, byte[] src, int from, int len)
    {
        if (index + len <= len)
        {
            Array.Copy(src, from, data, index, len);
        }

        return this;
    }

    /**
		 * 设置读写指针
		 **/
    public ByteBuf SetIndex(int readerIndex, int writerIndex)
    {
        if (readerIndex >= 0 && readerIndex <= writerIndex && writerIndex <= data.Length)
        {
            this.readerIndex = readerIndex;
            this.writerIndex = writerIndex;
        }

        return this;
    }

    /**
		 * 设置四字节整形
		 **/
    public ByteBuf SetInt(int index, int value)
    {
        if (index + 4 <= data.Length)
        {
            data[index++] = (byte)((value >> 24) & 0xff);
            data[index++] = (byte)((value >> 16) & 0xff);
            data[index++] = (byte)((value >> 8) & 0xff);
            data[index++] = (byte)(value & 0xff);
        }

        return this;
    }

    /// <summary>
    /// 设置小头整形
    /// </summary>
    /// <param name="index"></param>
    /// <param name="value"></param>
    /// <returns></returns>
    public ByteBuf SetIntLE(int index, int value)
    {
        if (index + 4 <= data.Length)
        {
            data[index++] = (byte)(value & 0xff);
            data[index++] = (byte)((value >> 8) & 0xff);
            data[index++] = (byte)((value >> 16) & 0xff);
            data[index++] = (byte)((value >> 24) & 0xff);
        }

        return this;
    }

    /**
		 * 设置两字节整形
		 **/
    public ByteBuf SetShort(int index, short value)
    {
        if (index + 2 <= data.Length)
        {
            data[index++] = (byte)((value >> 8) & 0xff);
            data[index++] = (byte)(value & 0xff);
        }

        return this;
    }

    /// <summary>
    /// 小头整形
    /// </summary>
    /// <param name="index"></param>
    /// <param name="value"></param>
    /// <returns></returns>
    public ByteBuf SetShortLE(int index, short value)
    {
        if (index + 2 <= data.Length)
        {
            data[index++] = (byte)(value & 0xff);
            data[index++] = (byte)((value >> 8) & 0xff);
        }

        return this;
    }

    /**
		 * 略过一些字节
		 **/
    public ByteBuf SkipBytes(int length)
    {
        if (readerIndex + length <= writerIndex)
        {
            readerIndex += length;
        }

        return this;
    }

    /**
		 * 剩余的可写字节数
		 **/
    public int WritableBytes()
    {
        return data.Length - writerIndex;
    }

    /**
		 * 写入一个字节
		 * 
		 **/
    public ByteBuf WriteByte(byte value)
    {
        this.Capacity(writerIndex + 1);
        this.data[writerIndex++] = value;
        return this;
    }

    /**
		 * 写入四字节整形
		 **/
    public ByteBuf WriteInt(int value)
    {
        Capacity(writerIndex + 4);
        data[writerIndex++] = (byte)((value >> 24) & 0xff);
        data[writerIndex++] = (byte)((value >> 16) & 0xff);
        data[writerIndex++] = (byte)((value >> 8) & 0xff);
        data[writerIndex++] = (byte)(value & 0xff);
        return this;
    }

    /// <summary>
    /// 写入四字节小头
    /// </summary>
    /// <param name="value"></param>
    /// <returns></returns>
    public ByteBuf WriteIntLE(int value)
    {
        Capacity(writerIndex + 4);
        data[writerIndex++] = (byte)(value & 0xff);
        data[writerIndex++] = (byte)((value >> 8) & 0xff);
        data[writerIndex++] = (byte)((value >> 16) & 0xff);
        data[writerIndex++] = (byte)((value >> 24) & 0xff);
        return this;
    }

    /**
		 * 写入两字节整形
		 **/
    public ByteBuf WriteShort(short value)
    {
        Capacity(writerIndex + 2);
        data[writerIndex++] = (byte)((value >> 8) & 0xff);
        data[writerIndex++] = (byte)(value & 0xff);
        return this;
    }

    /// <summary>
    /// 两字节小头
    /// </summary>
    /// <param name="value"></param>
    /// <returns></returns>
    public ByteBuf WriteShortLE(short value)
    {
        Capacity(writerIndex + 2);
        data[writerIndex++] = (byte)(value & 0xff);
        data[writerIndex++] = (byte)((value >> 8) & 0xff);
        return this;
    }

    /**
		 * 写入一部分字节
		 **/
    public ByteBuf WriteBytes(ByteBuf src)
    {
        int sum = src.writerIndex - src.readerIndex;
        Capacity(writerIndex + sum);
        if (sum > 0)
        {
            Array.Copy(src.data, src.readerIndex, data, writerIndex, sum);
            writerIndex += sum;
            src.readerIndex += sum;
        }

        return this;
    }

    /**
		 * 写入一部分字节
		 **/
    public ByteBuf WriteBytes(ByteBuf src, int len)
    {
        if (len > 0)
        {
            Capacity(writerIndex + len);
            Array.Copy(src.data, src.readerIndex, data, writerIndex, len);
            writerIndex += len;
            src.readerIndex += len;
        }

        return this;
    }

    /**
		 * 写入一部分字节
		 **/
    public ByteBuf WriteBytes(byte[] src)
    {
        int sum = src.Length;
        Capacity(writerIndex + sum);
        if (sum > 0)
        {
            Array.Copy(src, 0, data, writerIndex, sum);
            writerIndex += sum;
        }

        return this;
    }

    /**
		 * 写入一部分字节
		 **/
    public ByteBuf WriteBytes(byte[] src, int off, int len)
    {
        int sum = len;
        if (sum > 0)
        {
            Capacity(writerIndex + sum);
            Array.Copy(src, off, data, writerIndex, sum);
            writerIndex += sum;
        }

        return this;
    }

    /**
		 * 读取utf字符串（大头）
		 **/
    public string ReadUTF8()
    {
        short len = ReadShort(); // 字节数
        byte[] charBuff = new byte[len]; //
        Array.Copy(data, readerIndex, charBuff, 0, len);
        readerIndex += len;
        return Encoding.UTF8.GetString(charBuff);
    }

    /// <summary>
    /// 读取utf8（小头）
    /// </summary>
    /// <returns></returns>
    public string ReadUTF8LE()
    {
        short len = ReadShortLE(); // 字节数
        byte[] charBuff = new byte[len]; //
        Array.Copy(data, readerIndex, charBuff, 0, len);
        readerIndex += len;
        return Encoding.UTF8.GetString(charBuff);
    }

    /**
		 * 写入utf字符串
		 * 
		 **/
    public ByteBuf WriteUTF8(string value)
    {
        byte[] content = Encoding.UTF8.GetBytes(value.ToCharArray());
        int len = content.Length;
        Capacity(writerIndex + len + 2);
        WriteShort((short)len);
        Array.Copy(content, 0, data, writerIndex, len);
        writerIndex += len;
        return this;
    }

    /// <summary>
    /// 写入utf8（小头）
    /// </summary>
    /// <param name="value"></param>
    /// <returns></returns>
    public ByteBuf WriteUTF8LE(string value)
    {
        byte[] content = Encoding.UTF8.GetBytes(value.ToCharArray());
        int len = content.Length;
        Capacity(writerIndex + len + 2);
        WriteShortLE((short)len);
        Array.Copy(content, 0, data, writerIndex, len);
        writerIndex += len;
        return this;
    }

    /// <summary>
    /// 写指针
    /// </summary>
    /// <returns></returns>
    public int WriterIndex()
    {
        return writerIndex;
    }

    /// <summary>
    /// 移动写指针
    /// </summary>
    /// <param name="writerIndex"></param>
    /// <returns></returns>
    public ByteBuf WriterIndex(int writerIndex)
    {
        if (writerIndex >= readerIndex && writerIndex <= data.Length)
        {
            this.writerIndex = writerIndex;
        }

        return this;
    }

    /// <summary>
    /// 原始字节数组
    /// </summary>
    /// <returns></returns>
    public byte[] GetRaw()
    {
        return data;
    }
}